#pragma once
#include<vector>
#include<cassert>
#include"Log.hpp"
#define BUFFER_SIZE 1024//缓冲区大小
class Buffer{
    private:
        std::vector<char> _buffer;//缓冲区
        size_t _read_index;//读指针
        size_t _write_index;//写指针
    public:
        Buffer():_read_index(0),_write_index(0),_buffer(20){}
        ~Buffer(){}
        size_t GetBufferSize(){return _buffer.size();}    

        char *GetBegin(){return &_buffer[0];}//获取缓冲区首地址
        char *GetReadPointer(){return &_buffer[_read_index];}//获取读指针
        char *GetWritePointer(){return &_buffer[_write_index];}//获取写指针
        
        size_t HeadSpace(){return _read_index;}//头部空间
        size_t TailSpace(){return _buffer.size() - _write_index;}//尾部空间

        size_t ReadableSize(){return _write_index - _read_index;}//可读大小
        size_t WritableSize(){return _buffer.size() - ReadableSize();}//可写大小
        void TestPrintBuffer()
        {
            for(size_t i=_read_index;i<_write_index;i++){
                std::cout<<_buffer[i];
            }
            std::cout<<std::endl;
        }
        void Write(const void *data,size_t len)//不确定数据类型，但是最终都是强转成char*，然后按字节拷贝
        {
            //先判断是否具有足够的空间
            if(len > TailSpace() && len <= WritableSize()){//调整写的位置
            //     LOG("Head size : %ld",HeadSpace());
            //     LOG("Tail size : %ld",TailSpace());
            //     LOG("Writable size : %ld",WritableSize());
                size_t rdsize = ReadableSize();
                //重新调整读写指针
                _read_index = 0;
                _write_index = rdsize;
                // //然后拷贝数据
                // LOG("rdsize : %ld",rdsize);
                // LOG("write : %ld",_write_index);
                // LOG("read : %ld",_read_index);
                std::copy(GetReadPointer(),GetReadPointer()+rdsize,GetBegin());
                // TestPrintBuffer();
                //再写入数据
                std::copy((char*)data,((char*)data)+len,GetWritePointer());
                _write_index += len;//更新写指针
                // LOG("rdsize : %ld",rdsize);
                // LOG("write : %ld",_write_index);
                // LOG("read : %ld",_read_index);
                // TestPrintBuffer();
                return;
            }else if(len > WritableSize()){//缓冲区不够用，扩容
                _buffer.resize(_buffer.size() + len);
            }
            std::copy((char*)data,((char*)data)+len,GetWritePointer());
            _write_index += len;//更新写指针
            // TestPrintBuffer();
            // LOG("write : %ld",_write_index);
        }
        void Read(void *buffer,size_t len)//从读指针开始读len个字节，存入buffer
        {
            assert(ReadableSize() >= len);
            std::copy(GetReadPointer(),GetReadPointer()+len,(char *)buffer);
            // LOG("read : %ld",_read_index);
        }

        void ReadAndMove(void *buffer,size_t len)//从读指针开始读len个字节，存入buffer，并移动读指针
        {
            Read(buffer,len);
            _read_index += len;
            // LOG("readandmove : %ld",_read_index);
        }

        void Clear() //清空缓冲区
        {
            _read_index = 0;
            _write_index = 0;
        }
};
